package org.supper.auth.config;

import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.supper.auth.entity.Auth;
import org.supper.auth.entity.SmsCodeAuthenticationToken;
import org.supper.auth.entity.UserEntity;
import org.supper.auth.service.LoginService;
import org.supper.auth.utils.SpringUtil;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 * 授权码验证器
 * @author huqi
 */
public class SmsCodeAuthenticationProvider implements AuthenticationProvider {



    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        SmsCodeAuthenticationToken smsCodeAuthenticationToken = (SmsCodeAuthenticationToken) authentication;


        String mobile = (String) smsCodeAuthenticationToken.getPrincipal();
        LambdaQueryWrapper<UserEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserEntity::getUsername,mobile);
        queryWrapper.eq(UserEntity::getDataActive,1);
        LoginService loginService = SpringUtil.getBean(LoginService.class);
        UserEntity user = loginService.getOne(queryWrapper);
        if(null == user){
            throw new BadCredentialsException("Invalid mobile!");
        }
        //校验手机号验证码
        checkSmsCode(mobile);
        // 用户信息放入Auth中
        Auth auth = new Auth();
        auth.setUsername(user.getUsername());
        auth.setId(user.getId());
        auth.setHandeUrl(user.getHandeUrl());
        auth.setPassword(user.getPassword());
        auth.setAuthorities( AuthorityUtils.createAuthorityList("ADMIN"));
        return new SmsCodeAuthenticationToken(auth, auth.getAuthorities());
    }


    /**
     * 校验手机号与验证码的绑定关系是否正确
     *  todo 需要根据业务逻辑自行处理
     * @author javadaily
     * @date 2020/7/23 17:31
     * @param mobile 手机号码
     */
    private void checkSmsCode(String mobile) {
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        //获取验证码
        String smsCode = request.getParameter("verifyCode");
        if(StringUtils.isEmpty(smsCode) || !"666666".equals(smsCode)){
            throw new BadCredentialsException("Incorrect sms code,please check !");
        }
        //todo  手机号与验证码是否匹配
    }

    /**
     * ProviderManager 选择具体Provider时根据此方法判断
     * 判断 authentication 是不是 SmsCodeAuthenticationToken 的子类或子接口
     */
    @Override
    public boolean supports(Class<?> authentication) {
        return SmsCodeAuthenticationToken.class.isAssignableFrom(authentication);
    }
}